package com.blog4j.article.schedule;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.blog4j.article.entity.ArticleEntity;
import com.blog4j.article.entity.FavoriteEntity;
import com.blog4j.article.mapper.ArticleMapper;
import com.blog4j.article.mapper.FavoriteMapper;
import com.blog4j.common.constants.CacheConstants;
import com.blog4j.common.enums.ApproveEnum;
import com.blog4j.common.enums.ArticleStatusEnum;
import com.blog4j.common.enums.YesOrNoEnum;
import com.blog4j.common.utils.CommonUtil;
import com.blog4j.common.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Set;

/**
 * @author 98k灬
 * @version v1.0.0
 * @Description : 功能描述
 * @Create on : 2024/7/28 10:11
 **/
@Component
@EnableScheduling
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ArticleSchedule {
    private final RedisUtil redisUtil;
    private final ArticleMapper articleMapper;
    private final FavoriteMapper favoriteMapper;

    // 每隔10分钟执行一次
    @Scheduled(fixedRate = 1000 * 60 * 10)
    public void articleLike() {
        log.info("===== 执行点赞文章的定时任务： [{}] =====", CommonUtil.getCurrentDateTime());
        Set<String> keys = redisUtil.keys(CacheConstants.LIKE_ARTICLE_KEY);
        for (String key : keys) {
            Object obj = redisUtil.get(key);
            if (Objects.isNull(obj)) {
                continue;
            }
            int likes = Integer.parseInt((String) obj);
            String articleId = key.substring(CacheConstants.LIKE_ARTICLE_KEY.length());
            log.info("articleId: [{}]", articleId);

            LambdaQueryWrapper<ArticleEntity> wrapper = new LambdaQueryWrapper<ArticleEntity>()
                    .eq(ArticleEntity::getArticleId, articleId)
                    .eq(ArticleEntity::getStatus, ArticleStatusEnum.ONLINE.getCode())
                    .eq(ArticleEntity::getApproveStatus, ApproveEnum.PASS.getCode());
            ArticleEntity article = articleMapper.selectOne(wrapper);
            if (Objects.isNull(article)) {
                log.error("Article is not exist: [{}]", articleId);
                redisUtil.del(key);
                continue;
            }
            article.setLikes(article.getLikes() + likes);
            articleMapper.updateById(article);
            redisUtil.del(key);
        }
        log.info("===== 执行点赞文章的定时任务结束 =====");
    }

    // 每隔1分钟执行一次
    @Scheduled(fixedRate = 1000 * 60)
    public void articleFavorite() {
        log.info("===== 执行收藏文章的定时任务： [{}] =====", CommonUtil.getCurrentDateTime());
        Set<String> keys = redisUtil.keys(CacheConstants.FAVORITE_ARTICLE_KEY);
        for (String key : keys) {
            Object obj = redisUtil.get(key);
            if (Objects.isNull(obj)) {
                continue;
            }
            int favorite = Integer.parseInt((String) obj);
            String str = key.substring(CacheConstants.FAVORITE_ARTICLE_KEY.length());
            String[] split = str.split(CacheConstants.SPLIT);
            String userId = split[0];
            String articleId = split[1];
            log.info("user: [{}], articleId: [{}]", userId, articleId);
            LambdaQueryWrapper<FavoriteEntity> wrapper = new LambdaQueryWrapper<FavoriteEntity>()
                    .eq(FavoriteEntity::getArticleId, articleId)
                    .eq(FavoriteEntity::getUserId, userId);
            FavoriteEntity favoriteEntity = favoriteMapper.selectOne(wrapper);
            if (Objects.isNull(favoriteEntity)) {
                if (Objects.equals(favorite, YesOrNoEnum.YES.getCode())) {
                    FavoriteEntity favoriteEntity1 = FavoriteEntity.builder()
                            .userId(userId)
                            .articleId(articleId)
                            .createTime(CommonUtil.getCurrentDateTime())
                            .build();
                    favoriteMapper.insert(favoriteEntity1);
                }
            } else {
                if (Objects.equals(favorite, YesOrNoEnum.NO.getCode())) {
                    favoriteMapper.deleteById(favoriteEntity.getId());
                }
            }
            redisUtil.del(key);
        }
        log.info("===== 执行收藏文章的定时任务结束 =====");
    }

    // 每隔10分钟执行一次
    @Scheduled(fixedRate = 1000 * 60 * 10)
    public void articleViews() {
        log.info("===== 执行文章浏览量的定时任务： [{}] =====", CommonUtil.getCurrentDateTime());
        Set<String> keys = redisUtil.keys(CacheConstants.VIEWS_ARTICLE_KEY);
        for (String key : keys) {
            Object obj = redisUtil.get(key);
            if (Objects.isNull(obj)) {
                continue;
            }
            int views = Integer.parseInt((String) obj);
            String articleId = key.substring(CacheConstants.VIEWS_ARTICLE_KEY.length());
            log.info("articleId: [{}]", articleId);
            LambdaQueryWrapper<ArticleEntity> wrapper = new LambdaQueryWrapper<ArticleEntity>()
                    .eq(ArticleEntity::getArticleId, articleId)
                    .eq(ArticleEntity::getStatus, ArticleStatusEnum.ONLINE.getCode())
                    .eq(ArticleEntity::getApproveStatus, ApproveEnum.PASS.getCode());
            ArticleEntity article = articleMapper.selectOne(wrapper);
            if (Objects.isNull(article)) {
                log.error("Article is not exist: [{}]", articleId);
                redisUtil.del(key);
                continue;
            }
            article.setLikes(article.getViews() + views);
            articleMapper.updateById(article);
            redisUtil.del(key);
        }
        log.info("===== 执行文章浏览量的定时任务结束 =====");
    }
}
